package server.mapper;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import server.boot.MyClassLoader;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName Warpper
 * @Description
 * @Author wugz
 * @Date 2020/3/31 13:33
 * @Version 1.0
 */
public class Warpper {

    //存放静态html相关信息
    private Map<String, URI> mapUri = new HashMap<>();

    //存放web.xml相关信息
    private Map<String, HttpServlet> servletMap = new HashMap();

    public Warpper(Path path) throws Exception{
        /** 遍历文件树 */
        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                //获取到html
                if (file.toString().endsWith(".html")) {
                    //保存到mapper的静态map
                    mapUri.put("/"+file.getFileName().toString(), file.toUri());
                }
                //获取到xml
                if (file.toString().endsWith(".xml")) {
                    InputStream resourceAsStream = Files.newInputStream(file);
                    SAXReader saxReader = new SAXReader();
                    try {
                        Document document = saxReader.read(resourceAsStream);
                        Element rootElement = document.getRootElement();
                        List<Element> selectNodes = rootElement.selectNodes("//servlet");
                        for (int i = 0; i < selectNodes.size(); i++) {
                            Element element = selectNodes.get(i);
                            // <servlet-name>yumeko</servlet-name>
                            Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
                            String servletName = servletnameElement.getStringValue();
                            // <servlet-class>com.yumeko.YumekoServlet</servlet-class>
                            Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
                            String servletClass = servletclassElement.getStringValue();
                            // 根据servlet-name的值找到url-pattern
                            Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                            // /yumeko
                            String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                            URI uri = new URI(path.toUri()+servletClass.replace(".", "/")+".class");
                            //实例化外部servlet
                            MyClassLoader loader = new MyClassLoader(uri.getPath());
                            Class<?> aClass = loader.findClass(servletClass);
                            HttpServlet httpServlet = (HttpServlet)aClass.getConstructor().newInstance();
                            //保存到mapper的动态map
                            servletMap.put(urlPattern,httpServlet);
                        }
                    } catch (DocumentException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException | URISyntaxException | ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                return FileVisitResult.CONTINUE;
            }
        });

    }

    public Map<String, URI> getMapUri() {
        return mapUri;
    }

    public void setMapUri(Map<String, URI> mapUri) {
        this.mapUri = mapUri;
    }

    public Map<String, HttpServlet> getServletMap() {
        return servletMap;
    }

    public void setServletMap(Map<String, HttpServlet> servletMap) {
        this.servletMap = servletMap;
    }
}
